package com.microservice.salmon.service.category;

import com.microservice.salmon.db.entities.GoodsCategory;
import com.microservice.salmon.db.mapper.GoodsCategoryMapper;
import com.microservice.salmon.service.exception.ResourceException;
import com.salmon.common.ApiResponse;
import com.salmon.common.tree.ITree;
import com.salmon.common.tree.TreeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *
 * @author 王洪庆 2019-03-15 11:36
 */
@Service
@Slf4j
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private GoodsCategoryMapper goodsCategoryMapper;

    @Override
    public List<ITree> obtainAllGoodsCategoryTreeList() {
        List<GoodsCategory> categories = obtainAllGoodsCategoryList();
        return TreeUtils.getTreeList(categories);
    }

    public List<GoodsCategory> obtainAllGoodsCategoryList() {
        Example example = new Example(GoodsCategory.class);
        example.excludeProperties("createTime" ,"updateTime");
        example.orderBy("catSort").asc();
        example.createCriteria()
                .andEqualTo("dataFlag", true)
                .andEqualTo("isShow", 1);
        return goodsCategoryMapper.selectByExample(example);
    }


    /**
     * 获取品类子节点 平级， 获取categoryId 所有的平级子节点
     * @param categoryId 分类ID
     * @return
     */
    public List<GoodsCategory> getChildrenParallelCategory(Integer categoryId){
        Example example = new Example(GoodsCategory.class);
        example.excludeProperties("createTime" ,"updateTime", "dataFlag", "isShow", "isFloor");
        example.orderBy("catSort").asc();
        example.createCriteria()
                .andEqualTo("dataFlag", Boolean.TRUE)
                .andEqualTo("parentId", categoryId)
                .andEqualTo("isShow", Boolean.TRUE);
        List<GoodsCategory> categoryList = goodsCategoryMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(categoryList)){
            log.info("未找到当前分类的子分类");
        }
        return categoryList;
    }

    @Override
    public int addCategory(String categoryName, Integer parentId) {
        if(parentId == null || StringUtils.isBlank(categoryName)){
            throw new ResourceException(ApiResponse.Status.NOT_VALID_PARAM);
        }
        GoodsCategory category = new GoodsCategory();
        category.setName(categoryName);
        category.setParentId(parentId);
        return goodsCategoryMapper.insertSelective(category);
    }

    @Override
    public int updateCategoryName(Integer categoryId, String categoryName) {
        if(categoryId == null || StringUtils.isBlank(categoryName)){
            throw new ResourceException(ApiResponse.Status.NOT_VALID_PARAM);
        }
        GoodsCategory category = new GoodsCategory();
        category.setId(categoryId);
        category.setName(categoryName);
        return goodsCategoryMapper.updateByPrimaryKeySelective(category);
    }

    @Override
    public List<Integer> selectCategoryAndChildrenById(Integer categoryId) {
        Set<GoodsCategory> categorySet = new HashSet<>();
        findChildCategory(categorySet, categoryId);
        List<Integer> categoryIdList = new ArrayList<>();
        if(categoryId != null){
            for(GoodsCategory categoryItem : categorySet){
                categoryIdList.add(categoryItem.getId());
            }
        }
        return categoryIdList;
    }

    //递归算法,算出子节点
    private Set<GoodsCategory> findChildCategory(Set<GoodsCategory> categorySet ,Integer categoryId){
        GoodsCategory category = goodsCategoryMapper.selectByPrimaryKey(categoryId);
        if(category != null){
            categorySet.add(category);
        }
        //查找子节点,递归算法一定要有一个退出的条件
        List<GoodsCategory> categoryList = getChildrenParallelCategory(categoryId);
        for(GoodsCategory categoryItem : categoryList){
            findChildCategory(categorySet, categoryItem.getId());
        }
        return categorySet;
    }
}
